﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Meqs.Entity;
using Meqs.Logic.Interface;
using Meqs.Entity.Parameters;
using Castle.Services.Transaction;

namespace Meqs.Logic.Implement
{
    public class TeacherEvalSubmitRecordLogic : CommonLogic<TeacherEvalSubmitRecord, int>, ITeacherEvalSubmitRecordLogic
    {
        private ISchoolInfoLogic _schoolLogic;
        private ITeacherEvalListLogic _selLogic;
        private ITeacherEvalDetailLogic _sdLogic;
        private ITeacherEvalRemarkLogic _srLogic;
        private ITeacherEvalHistoryLogic _shLogic;
        private ITeacherEvalCatchLogic _spcLogic;
        private ITeacherEvalTypeCatchLogic _sptcLogic;
        private ITeacherEvalItemCatchLogic _spicLogic;
        private ITeacherEvalItemLogic _siLogic;
        private ITermInfoLogic _termLogic;
        public TeacherEvalSubmitRecordLogic(ISchoolInfoLogic schoolLogic,
                                        ITeacherEvalListLogic selLogic,
                                        ITeacherEvalDetailLogic sdLogic,
                                        ITeacherEvalRemarkLogic srLogic,
                                        ITeacherEvalHistoryLogic shLogic,
                                        ITeacherEvalCatchLogic spcLogic,
                                        ITeacherEvalTypeCatchLogic sptcLogic,
                                        ITeacherEvalItemCatchLogic spicLogic,
                                        ITeacherEvalItemLogic siLogic,
                                        ITermInfoLogic termLogic)
        {
            _schoolLogic = schoolLogic;
            _selLogic = selLogic;
            _sdLogic = sdLogic;
            _srLogic = srLogic;
            _shLogic = shLogic;
            _spcLogic = spcLogic;
            _sptcLogic = sptcLogic;
            _spicLogic = spicLogic;
            _siLogic = siLogic;
            _termLogic = termLogic;
        }


  
        #region Implementation of ICommonLogic<TeacherEvalSubmitRecord, int>

        /// <summary>
        /// 创建对象
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Create(TeacherEvalSubmitRecord entity)
        {
            return CreateObject(entity);
        }

        /// <summary>
        /// 更新对象
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Update(TeacherEvalSubmitRecord entity)
        {
            return UpdateObject(entity);
        }

        /// <summary>
        /// 删除对象
        /// </summary>
        /// <param name="entityId"></param>
        /// <returns></returns>
        public int Delete(int entityId)
        {
            return DeleteObject(entityId);
        }

        /// <summary>
        /// 删除所有对象
        /// </summary>
        /// <returns></returns>
        public int DeleteAll()
        {
            return DeleteAllObject();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityId"></param>
        /// <returns></returns>
        public TeacherEvalSubmitRecord FindById(int entityId)
        {
            return FindObjectById(entityId);
        }

        /// <summary>
        /// 检索对象数量
        /// </summary>
        /// <returns></returns>
        public int FindCount()
        {
            return FindObjectByCount();
        }

        /// <summary>
        /// 检索对象
        /// </summary>
        public IList<TeacherEvalSubmitRecord> FindAll()
        {
            return FindAllObject();
        }

        /// <summary>
        /// 检索对象数量
        /// </summary>
        /// <returns></returns>
        public int FindCount(Hashtable table)
        {
            return FindObjectByCount(table);
        }

        /// <summary>
        /// 检索对象
        /// </summary>
        public IList<TeacherEvalSubmitRecord> FindAll(Hashtable table)
        {
            return FindObject(table);
        }

        #endregion


        /// <summary>
        /// 获取教师评价提交记录
        /// </summary>
        /// <param name="clsID"></param>
        /// <param name="causeID"></param>
        /// <param name="reportType"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="schoolYear"></param>
        /// <param name="term"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        public TeacherEvalSubmitRecord GetRecordByMonth(int reportType, int year, int month, int? schoolYear, int? term, string schoolMark)
        {
            try
            {
                Hashtable ht = new Hashtable();
                ht.Add("SchoolMark", schoolMark);
                ht.Add("ReportDate", new DateTime(year, month, 1));
                ht.Add("ReportType", reportType);
                ht.Add("SchoolYear", schoolYear);
                ht.Add("Term", term);
                return FindCustomerByID<TeacherEvalSubmitRecord>("TeacherEvalSubmitRecord.GetRecordByMonth", ht);
            }
            catch (Exception)
            {
                return null;
            }
        }


        /// <summary>
        /// 获取教师评价提交记录
        /// </summary>
        /// <param name="clsID"></param>
        /// <param name="causeID"></param>
        /// <param name="reportType"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="schoolYear"></param>
        /// <param name="term"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        public TeacherEvalSubmitRecord GetRecordByMonth(int historyId,int teacherId,int managerId,int reportType, int year, int month, int? schoolYear, int? term, string schoolMark)
        {
            try
            {
                Hashtable ht = new Hashtable();
                ht.Add("historyId", historyId);
                ht.Add("SchoolMark", schoolMark);
                ht.Add("ReportDate", new DateTime(year, month, 1));
                ht.Add("ReportType", reportType);
                ht.Add("SchoolYear", schoolYear);
                ht.Add("Term", term);
                ht.Add("teacherId", teacherId);
                ht.Add("managerId", managerId);
                return FindCustomerByID<TeacherEvalSubmitRecord>("TeacherEvalSubmitRecord.GetRecordByMonth", ht);
            }
            catch (Exception)
            {
                return null;
            }
        }


        public TeacherEvalSubmitRecord GetRecordByTerm(int historyId, int teacherId, int managerId, int reportType, int year, int month, int? schoolYear, int? term, string schoolMark)
        {
            try
            {
                Hashtable ht = new Hashtable();
                ht.Add("historyId", historyId);
                ht.Add("SchoolMark", schoolMark);
                //ht.Add("ReportDate", new DateTime(year, month, 1));
                ht.Add("SchoolYear", schoolYear);
                ht.Add("Term", term);
                ht.Add("teacherId", teacherId);
                if (managerId > 0)
                    ht.Add("managerId", managerId);
                return FindCustomerByID<TeacherEvalSubmitRecord>("TeacherEvalSubmitRecord.GetRecordByTerm", ht);
            }
            catch (Exception)
            {
                return null;
            }
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        /// <param name="historyId"></param>
        /// <param name="reportType">3-月评，4-学期评</param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="schoolYear"></param>
        /// <param name="term"></param>
        /// <param name="teacherID"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Supported)]
        public bool SaveOrUpdateRecord(IList<VItems> list,int historyId, int reportType, int year, int month, int? schoolYear, int? term, int ManagerID, string schoolMark)
        {
            try
            {  
                if (schoolYear == null || term == null)
                {
                    SchoolInfo school = _schoolLogic.FindBySchoolMark(schoolMark);
                    schoolYear = school.SchoolYear;
                    term = school.SchoolTerm;
                }
                TeacherEvalList sel = null;
                TeacherEvalSubmitRecord ssr = null;
                TeacherEvalHistory sh = null;
                DateTime termStart = new DateTime();
                if (reportType == 4)
                {
                    List<TermInfo> termInfo = (List<TermInfo>)_termLogic.FindTermInfo(schoolMark, (int)schoolYear, (int)term);
                    termStart = (DateTime)termInfo[0].StartDate; 

                    //学期评估所取的开始时间是学期开始时间，且无结束时间
                    sel = _selLogic.GetEvalListByTerm(historyId, termStart.Year, termStart.Month, schoolYear, term, schoolMark);
                    ssr = GetRecordByTerm( historyId,list[0].TeacherID,ManagerID,reportType, year, month, schoolYear, term, schoolMark);//TODO:添加被平人id作为查询条件
                    sh = _shLogic.GetHistoryRecordByTerm(historyId, (int)schoolYear, (int)term, schoolMark);
                }
                else
                {
                    //月、周、日评估所取的开始和结束时间可计算
                    sel = _selLogic.GetEvalList(historyId, reportType, year, month, schoolYear, term, schoolMark);
                    ssr = GetRecordByMonth( historyId,list[0].TeacherID,ManagerID, reportType, year, month, schoolYear, term, schoolMark);
                    sh = _shLogic.GetHistoryRecordByTerm( historyId,(int)schoolYear, (int)term, schoolMark);
                }

                // 如果德育评价记录为空，则插入一条记录
                if (sel == null)
                {
                    if (reportType == 4)
                    { 
                        sel = new TeacherEvalList();
                        sel.HistoryID = historyId;
                        sel.StartTime = termStart;
                        sel.Attribute = reportType;

                        int selID = _selLogic.InsertTeacherEvalEvalList(sel, schoolMark);
                        sel.RID = selID;
                    }
                    else
                    {
                        sel = new TeacherEvalList();
                        sel.HistoryID = historyId;
                        sel.StartTime = new DateTime(year, month, 1);
                        sel.Attribute = reportType;

                        int selID = _selLogic.InsertTeacherEvalEvalList(sel, schoolMark);
                        sel.RID = selID;
                    }
                }

                // 如果德育评价提交记录为空，则插入一条记录
                if (ssr == null)
                {
                    ssr = new TeacherEvalSubmitRecord();
                    ssr.ListID = sel.RID;
                    ssr.ManagerID = ManagerID;
                    ssr.Status = 1;
                    ssr.TeacherID = list[0].TeacherID;

                    int ssrID = InsertTeacherEvalSubmitRecord(ssr, schoolMark);
                    ssr.RID = ssrID;
                }

                // 清空评价和备注
                DeleteAllRecord(ssr.RID, schoolMark);
                IList<int> teacherIDList = new List<int>();
                if (list == null) return true;
                Dictionary<int, double> dicMpc = new Dictionary<int, double>();
                Dictionary<DicKeyTeach, double> dicMptc = new Dictionary<DicKeyTeach, double>();
                Dictionary<DicKeyTeach, double[]> dicMpic = new Dictionary<DicKeyTeach, double[]>();
                // 保存评价和备注
                foreach (VItems item in list)
                {
                    if (!string.IsNullOrEmpty(item.Remark))
                    {
                        TeacherEvalRemark sr = new TeacherEvalRemark();
                        sr.RecordID = ssr.RID;
                        sr.TeacherID = item.TeacherID;
                        sr.Data = item.Remark;

                        _srLogic.InsertTeacherEvalRemark(sr, schoolMark);
                    }
                    if (item.TeacherItems != null && item.TeacherItems.Count > 0)
                    {
                        foreach (TeacherItems stuItem in item.TeacherItems)
                        {
                            TeacherEvalDetail sd = new TeacherEvalDetail();
                            sd.Itemid = stuItem.MoralityItemID;
                            sd.RecordID = ssr.RID;
                            sd.TeacherID = item.TeacherID;
                            sd.Param = stuItem.Param;

                            _sdLogic.InsertTeacherEvalDetail(sd, schoolMark);
                            if (!teacherIDList.Contains((int)sd.TeacherID)) teacherIDList.Add((int)sd.TeacherID);


                            #region 计算每套题目的总分

                            if (dicMpc.ContainsKey((int)sd.TeacherID))
                            //if (ContainsKey(dicMpc, (int)sd.StudentID))
                            {
                                double allScore = dicMpc[(int)sd.TeacherID];
                                allScore += stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                                dicMpc[(int)sd.TeacherID] = allScore;
                            }
                            else
                            {
                                dicMpc[(int)sd.TeacherID] = stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                            }

                            #endregion

                            TeacherEvalItem si = _siLogic.GetItemByID(schoolMark, (int)sd.Itemid);
                            #region 计算每道大题的分数

                            DicKeyTeach mptcKey = new DicKeyTeach((int)sd.TeacherID, (int)si.TypeID);
                            if (dicMptc.ContainsKey(mptcKey)) 
                            {
                                double allScore = dicMptc[(DicKeyTeach)mptcKey];
                                allScore += stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                                dicMptc[mptcKey] = allScore;
                            }
                            else
                            {
                               dicMptc[mptcKey] = stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                            }

                            #endregion

                            #region 计算每道小题的分数

                            DicKeyTeach mpicKey = new DicKeyTeach((int)sd.TeacherID, si.RID);
                            if (dicMpic.ContainsKey(mpicKey))
                            //if (ContainsKey(dicMpic, mpicKey))
                            {
                                double allScore = dicMpic[mpicKey][0];
                                double allParam = dicMpic[mpicKey][1];
                                allScore += stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                                allParam += stuItem.Param;
                                dicMpic[mpicKey] = new double[] { allScore, allParam };
                            }
                            else
                            {
                                double allScore = stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                                double allParam = stuItem.Param;
                                dicMpic[mpicKey] = new double[] { allScore, allParam };
                            }

                            #endregion
                        }
                    }
                }

                foreach (int teacherId in teacherIDList)
                {
                    // 计算缓存表

                    // 1. 将结果汇总到每张单据中每个人的总分(表:StuCausePersonCatch)
                    int recordID = ssr.RID;
                    // 先删除
                    _spcLogic.DeleteTeacherEvalCatch(teacherId, recordID, schoolMark);
                    // 再插入

                    TeacherEvalCatch mpc = new TeacherEvalCatch();
                    mpc.RecordID = recordID;
                    mpc.TeacherID = teacherId;
                    double score = dicMpc[teacherId];
                    mpc.Score = score;
                    mpc.Dirty = 0;
                    _spcLogic.InsertTeacherEvalCatch(mpc,schoolMark);

                    // 2. 将结果汇总到每张单据中每道大题每个人的得分(表:StuCausePersonTypeCatch)
                    _sptcLogic.DeleteTeacherEvalTypeCatch(teacherId, recordID, schoolMark);
                    foreach (KeyValuePair<DicKeyTeach, double> dictionary in dicMptc)
                    {
                        if (dictionary.Key.TeacherID != teacherId) continue;
                        TeacherEvalTypeCatch mptc = new TeacherEvalTypeCatch();
                        mptc.Dirty = 0;
                        mptc.RecordID = recordID;
                        mptc.Score = dictionary.Value;
                        mptc.TeacherID = teacherId;
                        mptc.TypeID = dictionary.Key.ItemID;
                        _sptcLogic.InsertTeacherEvalTypeCatch(mptc, schoolMark);
                    }

                    // 3. 将结果汇总到每张单据中每道小题每个人的得分(表:StuCausePersonItemCatch)
                    _spicLogic.DeleteTeacherEvalItemCatch(teacherId, recordID, schoolMark);
                    foreach (KeyValuePair<DicKeyTeach, double[]> dictionary in dicMpic)
                    {
                        if (dictionary.Key.TeacherID != teacherId) continue;
                        TeacherEvalItemCatch mpic = new TeacherEvalItemCatch();
                        mpic.Dirty = 0;
                        mpic.ItemID = dictionary.Key.ItemID;
                        mpic.Param = dictionary.Value[1];
                        mpic.RecordID = recordID; 
                        mpic.Score = dictionary.Value[0];
                        mpic.TeacherID = teacherId;
                        _spicLogic.InsertTeacherEvalItemCatch(mpic, schoolMark);
                    }
                }

                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }


        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="moralitySubmitRecord"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        public int InsertTeacherEvalSubmitRecord(TeacherEvalSubmitRecord moralitySubmitRecord, string schoolMark)
        {
            Hashtable ht = new Hashtable();
            ht.Add("TeacherEvalSubmitRecord", moralitySubmitRecord);
            ht.Add("SchoolMark", schoolMark);
            return (int)InsertCustomer("TeacherEvalSubmitRecord.InsertTeacherEvalSubmitRecord", ht);
        }


        /// <summary>
        /// 清空教师的detail和remark的记录
        /// </summary>
        /// <param name="recordID"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        public int DeleteAllRecord(int recordID, string schoolMark)
        {
            Hashtable ht = new Hashtable();
            ht.Add("RecordID", recordID);
            ht.Add("SchoolMark", schoolMark);
            return DeleteCustomer("TeacherEvalSubmitRecord.DeleteAllRecord", ht);
        }

        /// <summary>
        /// 获取学生评教的教师评估数据
        /// </summary>
        /// <param name="schoolMark"></param>
        /// <param name="clsId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public IList<TeacherEvalSubmitRecord> ValidateTeachIsEvaluate(int historyID, string schoolMark, int clsId,int userId)
        {
            Hashtable table = new Hashtable();
            table.Add("SchoolMark", schoolMark);
            table.Add("ClsID", clsId);
            table.Add("ManagerID", userId);
            table.Add("HistoryID", historyID);

            return FindCustomer<TeacherEvalSubmitRecord>("TeacherEvalSubmitRecord.ValidateTeachIsEvaluate", table);
        }


        /// <summary>
        /// 获取学生评教的教师评估数据
        /// </summary>
        /// <param name="schoolMark"></param>
        /// <param name="clsId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public int ValidateTeachIsEvaluate(string schoolMark, int historyId, int managerId, int teacherId)
        {
            Hashtable table = new Hashtable();
            table.Add("SchoolMark", schoolMark);
            table.Add("HistoryID", historyId);
            table.Add("ManagerID", managerId);
            table.Add("TeacherID", teacherId);

            return FindCustomerByCount("TeacherEvalSubmitRecord.ValidateTeachIsEvaluate2", table);
        }

    }


    internal class DicKeyTeach
    {
        public DicKeyTeach()
        {
        }

        private int _teacherID;
        private int _itemID;

        public DicKeyTeach(int teacherID, int itemID)
        {
            _teacherID = teacherID;
            _itemID = itemID;
        }

        public int TeacherID
        {
            get { return _teacherID; }
            set { _teacherID = value; }
        }

        public int ItemID
        {
            get { return _itemID; }
            set { _itemID = value; }
        }

        public bool Equals(DicKeyTeach other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return other._teacherID == _teacherID && other._itemID == _itemID;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof(DicKeyTeach)) return false;
            return Equals((DicKeyTeach)obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return (_teacherID * 397) ^ _itemID;
            }
        }
    }
}
